package com.gurun.camera.addDevice.presenter;

import com.danale.sdk.Danale;
import com.danale.sdk.device.SdkManager;
import com.danale.sdk.device.bean.LocalDevice;
import com.danale.sdk.device.callback.OnLocalSearchCallback;
import com.danale.sdk.utils.LogUtil;
import com.danale.video.jni.DanaSmartLink;
import com.gurun.camera.addDevice.entity.DeviceInfoEntity;
import com.gurun.camera.addDevice.model.IQueryDevInfoModel;
import com.gurun.camera.addDevice.model.QueryDevModelImpl;
import com.gurun.camera.addDevice.util.DevInfoEntityCache;
import com.gurun.camera.addDevice.view.ISearchDevView;
import java.util.List;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;

/**
 * Created by Administrator on 2016/9/14.
 */
public class SearchDevPresenterImpl implements ISearchDevPresenter,OnLocalSearchCallback,DanaSmartLink.SearchCallbackListener {
    private static final String TAG = SearchDevPresenterImpl.class.getSimpleName();
    private ISearchDevView mView;
    private IQueryDevInfoModel mQueryModel;
    private volatile boolean mIsSearching = false;
    private Subscription mOnSearchDeviceInfoResultBack;

    public SearchDevPresenterImpl(ISearchDevView view) {
        mView = view;
        mQueryModel = new QueryDevModelImpl();
    }

    /**
     * video and iot device search
     */

    @Override
    public void startSearchDevice() {
        setIsSearching(true);

        //video dev search
        SdkManager sdk = Danale.get().getDeviceSdk();
        sdk.cbDispatcher().searchDispatcher().register(this);
        sdk.command().startSearchLocalDevice();

        //iot dev search
        DanaSmartLink.getInstance().startSearchDevices(this);

        if(mView != null){
            mView.onStartSearchingDevice();
        }

        queryDeviceInfo();
    }

    @Override
    public void stopSearchDevice() {
        setIsSearching(false);

        //stop video dev search
        SdkManager sdk = Danale.get().getDeviceSdk();
        sdk.cbDispatcher().searchDispatcher().unregister();
        sdk.command().stopSearchLocalDevice();

        //stop iot dev search
        DanaSmartLink.getInstance().stopSearchDevices();

        if(mOnSearchDeviceInfoResultBack != null && !mOnSearchDeviceInfoResultBack.isUnsubscribed()){
            mOnSearchDeviceInfoResultBack.unsubscribe();
        }
        if(mView != null){
            mView.onStopSearchingDevice();
        }
    }

    @Override
    public void onDeviceSearched(int status, LocalDevice device) {
        if(DevInfoEntityCache.getInstance().getDeviceInfoEntity(device.getDevice_id()) == null){
            DeviceInfoEntity entity = new DeviceInfoEntity();
            entity.setDeviceId(device.getDevice_id());
            DevInfoEntityCache.getInstance().updateDevInfo(entity);
        }

        LogUtil.d(TAG,"onDeviceSearched: deviceId = " + device.getDevice_id());
    }


    private void queryDeviceInfo(){
        LogUtil.d(TAG,"queryDeviceInfo");
        mOnSearchDeviceInfoResultBack = Observable.interval(0, 10000, TimeUnit.MILLISECONDS)
                .flatMap(new Func1<Long, Observable<List<DeviceInfoEntity>>>() {
                    @Override
                    public Observable<List<DeviceInfoEntity>> call(Long aLong) {
                        LogUtil.d(TAG, "onSearchDeviceInfoResultBack flatMap");
                        return mQueryModel.obtainDeviceInfos(DevInfoEntityCache.getInstance().getDeviceInfoEntityList());
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<List<DeviceInfoEntity>>() {
                    @Override
                    public void call(List<DeviceInfoEntity> searchDeviceInfoEntities) {
                        if (mView != null) {
                            LogUtil.d(TAG, "onSearchDeviceInfoResultBack");
                            DevInfoEntityCache.getInstance().updateSearchDevList(searchDeviceInfoEntities);
                            List<DeviceInfoEntity> deviceInfoEntityList = DevInfoEntityCache.getInstance().getDeviceInfoEntityList();
                            DevInfoEntityCache.getInstance().sortList(deviceInfoEntityList);
                            mView.onSearchDeviceInfoResultBack(deviceInfoEntityList);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        LogUtil.d(TAG, "onSearchDeviceInfoResultBack throwable");
                        queryDeviceInfo();
                    }
                });
    }

    private void setIsSearching(boolean searching){
        mIsSearching = searching;
    }

    private boolean isIsSearching(){
        return mIsSearching;
    }


    @Override
    public void onSearchCallback(String s) {
        if(DevInfoEntityCache.getInstance().getDeviceInfoEntity(s) == null){
            DeviceInfoEntity entity = new DeviceInfoEntity();
            entity.setDeviceId(s);
            DevInfoEntityCache.getInstance().updateDevInfo(entity);
        }
        LogUtil.d("iotDevSearch","onSearchCallback: deviceId = " +s );
    }

    @Override
    public void onSearchError() {

    }
}
